import unittest
from datetime import datetime, timedelta
from app import create_app
from models import db, Product, Location, Inventory, Batch

class WarehouseTestCase(unittest.TestCase):
    
    def setUp(self):
        self.app = create_app('testing')
        self.client = self.app.test_client()
        self.app_context = self.app.app_context()
        self.app_context.push()
        db.create_all()
        
        # 添加测试数据
        p1 = Product(name="测试商品1", barcode="123456", min_stock=10)
        p2 = Product(name="测试商品2", barcode="654321", min_stock=5)
        db.session.add_all([p1, p2])
        
        loc1 = Location(code="A-01", area="A区")
        loc2 = Location(code="B-01", area="B区")
        db.session.add_all([loc1, loc2])
        
        inv1 = Inventory(product_id=1, location_id=1, quantity=8)
        inv2 = Inventory(product_id=1, location_id=2, quantity=5)
        inv3 = Inventory(product_id=2, location_id=1, quantity=3)
        db.session.add_all([inv1, inv2, inv3])
        
        batch1 = Batch(
            product_id=1,
            batch_number="B2023001",
            quantity=10,
            production_date=datetime.now().date() - timedelta(days=30),
            expiry_date=datetime.now().date() + timedelta(days=15),
            supplier="测试供应商",
            purchase_price=5.0,
            location_id=1
        )
        db.session.add(batch1)
        
        db.session.commit()
    
    def tearDown(self):
        db.session.remove()
        db.drop_all()
        self.app_context.pop()
    
    def test_low_stock_alert(self):
        # 测试库存预警
        response = self.client.get('/api/warehouse/inventory/low-stock')
        self.assertEqual(response.status_code, 200)
        data = response.get_json()
        self.assertEqual(len(data), 2)  # 两个商品都低于库存阈值
        
        # 测试自定义阈值
        response = self.client.get('/api/warehouse/inventory/low-stock?threshold=10')
        self.assertEqual(response.status_code, 200)
        data = response.get_json()
        self.assertEqual(len(data), 1)  # 只有一个商品库存低于10
    
    def test_product_search(self):
        # 测试商品查询
        response = self.client.get('/api/warehouse/products/search?keyword=测试')
        self.assertEqual(response.status_code, 200)
        data = response.get_json()
        self.assertEqual(len(data), 2)
        
        response = self.client.get('/api/warehouse/products/search?barcode=123456')
        self.assertEqual(response.status_code, 200)
        data = response.get_json()
        self.assertEqual(len(data), 1)
        self.assertEqual(data[0]['name'], "测试商品1")
    
    def test_location_usage(self):
        # 测试货位使用情况
        response = self.client.get('/api/warehouse/locations/usage')
        self.assertEqual(response.status_code, 200)
        data = response.get_json()
        self.assertEqual(len(data), 2)
        self.assertEqual(data[0]['code'], "A-01")
        self.assertEqual(data[0]['product_count'], 2)  # A-01有两个商品
    
    def test_expiring_batches(self):
        # 测试即将过期的批次
        response = self.client.get('/api/warehouse/batches/expiring?days=20')
        self.assertEqual(response.status_code, 200)
        data = response.get_json()
        self.assertEqual(len(data), 1)
        self.assertEqual(data[0]['batch_number'], "B2023001")
    
    def test_add_batch(self):
        # 测试添加批次
        data = {
            "product_id": 2,
            "batch_number": "B2023002",
            "quantity": 20,
            "production_date": "2023-01-01",
            "expiry_date": "2023-12-31",
            "supplier": "新供应商",
            "purchase_price": 8.5,
            "location_id": 2
        }
        response = self.client.post('/api/warehouse/batches', json=data)
        self.assertEqual(response.status_code, 201)
        
        # 检查库存是否更新
        inventory = Inventory.query.filter_by(product_id=2, location_id=2).first()
        self.assertEqual(inventory.quantity, 20)
    
    def test_move_inventory(self):
        # 测试移动库存
        data = {
            "product_id": 1,
            "from_location_id": 1,
            "to_location_id": 2,
            "quantity": 5
        }
        response = self.client.post('/api/warehouse/inventory/move', json=data)
        self.assertEqual(response.status_code, 200)
        
        # 检查源货位库存
        from_inv = Inventory.query.filter_by(product_id=1, location_id=1).first()
        self.assertEqual(from_inv.quantity, 3)
        
        # 检查目标货位库存
        to_inv = Inventory.query.filter_by(product_id=1, location_id=2).first()
        self.assertEqual(to_inv.quantity, 10)

if __name__ == '__main__':
    unittest.main()
